home *** CD-ROM | disk | FTP | other *** search
- (define (sort! x . y)
- (define test <=)
- (define (interchange x i j)
- (let ((tmp (vector-ref x i)))
- (vector-set! x i (vector-ref x j))
- (vector-set! x j tmp)))
- (define (qsort x m n)
- (if (< m n)
- (do ((i m) (j (1+ n))
- (k (begin (interchange x m (quotient (+ m n) 2))
- (vector-ref x m))))
- ((>= i j) (interchange x m j)
- (qsort x m (-1+ j))
- (qsort x (1+ j) n) x)
- (set! i (1+ i))
- (while (and (test (vector-ref x i) k) (< i n))
- (set! i (1+ i)))
- (set! j (-1+ j))
- (while (and (test k (vector-ref x j)) (> j m))
- (set! j (-1+ j)))
- (when (< i j) (interchange x i j)))))
- (define (merge-list x y)
- (cond ((null? x) y)
- ((null? y) x)
- (else (if (test (car x) (car y))
- (cons (car x) (merge-list (cdr x) y))
- (cons (car y) (merge-list x (cdr y)))))))
- (define (merge-sort x)
- (if (null? x)
- nil
- (do ((ptr1 x (cdr ptr1))
- (ptr2 (cdr x) (cdr ptr2)))
- ((or (null? ptr2)
- (test (car ptr2) (car ptr1)))
- (set-cdr! ptr1 nil)
- (merge-list x (merge-sort ptr2))))))
- (when (pair? y)
- (if (proc? (car y))
- (set! test (car y))
- (error "second arg to sort! must be a procedure" (car y))))
- (cond ((vector? x) (qsort x 0 (-1+ (vector-length x))) x)
- ((pair? x) (merge-sort x))
- (else (error "first arg to sort! must be a vector or a list" x))))
-